package org.xxpay.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xxpay.core.common.constant.MchConstant;
import org.xxpay.core.common.util.AssignWeightUtil;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.entity.PayPassageAccount;
import org.xxpay.core.entity.PayPassageAccountExample;
import org.xxpay.core.service.IPayPassageAccountService;
import org.xxpay.service.dao.mapper.PayPassageAccountMapper;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author: dingzhiwei
 * @date: 2018/5/3
 * @description: 支付通道账户
 */
@Service
public class PayPassageAccountServiceImpl implements IPayPassageAccountService {

    @Autowired
    private PayPassageAccountMapper payPassageAccountMapper;

    private static final MyLog _log = MyLog.getLog(PayPassageAccountServiceImpl.class);

    @Override
    public int add(PayPassageAccount payPassageAccount) {
        return payPassageAccountMapper.insertSelective(payPassageAccount);
    }

    @Override
    @Transactional
    public int addByTC(PayPassageAccount payPassageAccount, List<String> accountNoList) {

        //插入主表
        payPassageAccountMapper.insertSelective(payPassageAccount);

        return 1;
    }

    @Override
    public int update(PayPassageAccount payPassageAccount) {
        return payPassageAccountMapper.updateByPrimaryKeySelective(payPassageAccount);
    }

    @Override
    @Transactional
    public int updateByTC(PayPassageAccount payPassageAccount, List<String> accountNoList) {

        //更新主表
        payPassageAccountMapper.updateByPrimaryKeySelective(payPassageAccount);

        return 1;
    }

    @Override
    public PayPassageAccount findById(Integer id) {
        return payPassageAccountMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<PayPassageAccount> select(int offset, int limit, PayPassageAccount payPassageAccount) {
        PayPassageAccountExample example = new PayPassageAccountExample();
        example.setOrderByClause("createTime DESC");
        example.setOffset(offset);
        example.setLimit(limit);
        PayPassageAccountExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, payPassageAccount);
        return payPassageAccountMapper.selectByExample(example);
    }

    @Override
    public Integer count(PayPassageAccount payPassageAccount) {
        PayPassageAccountExample example = new PayPassageAccountExample();
        PayPassageAccountExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, payPassageAccount);
        return payPassageAccountMapper.countByExample(example);
    }

    @Override
    public List<PayPassageAccount> selectAll(PayPassageAccount payPassageAccount) {
        PayPassageAccountExample example = new PayPassageAccountExample();
        example.setOrderByClause("createTime DESC");
        PayPassageAccountExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, payPassageAccount);
        return payPassageAccountMapper.selectByExample(example);
    }

    @Override
    public List<PayPassageAccount> selectAllByPassageId(Integer payPassageId) {
        PayPassageAccount payPassageAccount = new PayPassageAccount();
        payPassageAccount.setPayPassageId(payPassageId);
        payPassageAccount.setStatus(MchConstant.PUB_YES);
        return selectAll(payPassageAccount);
    }

    @Override
    public List<PayPassageAccount> selectAllByPayOrderCount(Integer payPassageId) {
        return payPassageAccountMapper.selectAllByPayOrderCount(payPassageId);
    }

    @Override
    public List<PayPassageAccount> selectAllByPayOrderTime(Integer payPassageId) {
        return payPassageAccountMapper.selectAllByPayOrderTime(payPassageId);
    }

    @Override
    public List<PayPassageAccount> selectAllByPayOrderAmount(Integer payPassageId) {
        return payPassageAccountMapper.selectAllByPayOrderAmount(payPassageId);
    }

    @Override
    public List<PayPassageAccount> selectAllByPayOrderPollWeight(Integer payPassageId, Integer pollOrderTime) {
        Map param = new HashMap();
        param.put("payPassageId", payPassageId);
        param.put("pollOrderTime", pollOrderTime);
        LinkedList<PayPassageAccount> payPassageAccountLinkedList = new LinkedList<>();
        List<PayPassageAccount> payPassageAccountList = payPassageAccountMapper.selectAllByPayOrderPollWeight(param);

        if(payPassageAccountList == null) return payPassageAccountList;

        // 一个直接返回
        if(payPassageAccountList.size() == 1) {
            return payPassageAccountList;
        }
        // 多个需要计算权重比例
        LinkedList<AssignWeightUtil.AssignWeight> list = new LinkedList<>();
        for(PayPassageAccount payPassageAccount : payPassageAccountList) {
            AssignWeightUtil.AssignWeight assignWeight = new AssignWeightUtil.AssignWeight();
            assignWeight.setName(payPassageAccount.getId().toString());
            assignWeight.setWeight(payPassageAccount.getPollWeight());
            assignWeight.setCount(payPassageAccount.getOrderNum());
            list.add(assignWeight);
        }
        // 计算出权重最高的一个
        AssignWeightUtil.AssignWeight firstAssignWeight = AssignWeightUtil.assignUniform(list);
        for(PayPassageAccount payPassageAccount : payPassageAccountList) {

            if(firstAssignWeight.getName().equals(payPassageAccount.getId().toString())) {
                payPassageAccountLinkedList.addFirst(payPassageAccount);  // 加入到集合第一个位置
            }else {
                payPassageAccountLinkedList.add(payPassageAccount);
            }
        }
        return payPassageAccountLinkedList;
    }

    @Override
    public List<Map> selectList(int i, int pageSize, Integer payPassageId, Byte status, String createTimeStart, String createTimeEnd, boolean isOnlySupplier) {
        Map param = new HashMap();
        param.put("offset",i);
        param.put("limit",pageSize);
        if (payPassageId != null) param.put("payPassageId",payPassageId);
        if (status != null && status != -99) param.put("status",status);
        if (StringUtils.isNotBlank(createTimeStart)) param.put("createTimeStart",createTimeStart);
        if (StringUtils.isNotBlank(createTimeEnd)) param.put("createTimeEnd",createTimeEnd);
        if(isOnlySupplier) param.put("isOnlySupplier", true);
        return payPassageAccountMapper.selectList(param);
    }

    @Override
    public int deleteByIds(List<Integer> ids){
        PayPassageAccountExample exa = new PayPassageAccountExample();
        exa.createCriteria().andIdIn(ids);
        return payPassageAccountMapper.deleteByExample(exa);
    }

    @Override
    public int updateByExample(PayPassageAccount payPassageAccount) {
        PayPassageAccountExample exa = new PayPassageAccountExample();
        PayPassageAccountExample.Criteria criteria = exa.createCriteria();
        if (payPassageAccount.getId() != null) criteria.andIdEqualTo(payPassageAccount.getId());
        if (payPassageAccount.getPassageMchId() != null) criteria.andPassageMchIdEqualTo(payPassageAccount.getPassageMchId());
        if (payPassageAccount.getPayPassageId() != null) criteria.andPayPassageIdEqualTo(payPassageAccount.getPayPassageId());
        return payPassageAccountMapper.updateByExampleSelective(payPassageAccount, exa);
    }

    void setCriteria(PayPassageAccountExample.Criteria criteria, PayPassageAccount obj) {
        if(obj != null) {
            if(obj.getPayPassageId() != null) criteria.andPayPassageIdEqualTo(obj.getPayPassageId());
            if(obj.getPassageMchId() != null) criteria.andPassageMchIdEqualTo(obj.getPassageMchId());
            if(obj.getRiskStatus() != null && obj.getRiskStatus().byteValue() != -99) criteria.andRiskStatusEqualTo(obj.getRiskStatus());
            if(obj.getStatus() != null && obj.getStatus().byteValue() != -99) criteria.andStatusEqualTo(obj.getStatus());

        }
    }

}
